#pragma once
#include "../Exception.h"
#include "../ResultSet.h"
#include "../DataBase.h"
#include <sstream>
#include "ado2.h"

namespace Arrow_DB_Assist
{


class AdoAssistant
	/// MySql data base class
{
	friend class DataBase<AdoAssistant>;

public:

	AdoAssistant()
	{
		_connectionHandlerPtr = NULL;
		_pAdoRS = NULL;
	}

	virtual ~AdoAssistant()
	{
	}

	void connect(const std::string& server, const std::string& user, const std::string& password, const std::string& database)
	{		
		_connectionHandlerPtr = NULL; 
		std::ostringstream s;
		s	<<_T("Provider=SQLOLEDB.1;Persist Security Info=False;User ID=")
			<<user
			<<_T(";Password =")
			<<password
			<<_T(";Initial Catalog=")
			<<database
			<<_T(";Data Source=")
			<<server
			<<_T(";");
		_connectionHandlerPtr = new CADODatabase;
		_connectionHandlerPtr->SetConnectionString(s.str().c_str());
		try
		{
			_connectionHandlerPtr->Open();
		}
		catch (CADOException& e)
		{
			TRACE(e.GetErrorMessage());
			delete _connectionHandlerPtr;
			_connectionHandlerPtr = NULL;
		}
	}

	void execute(const std::string& sql)
	{
		if (_pAdoRS != NULL)
		{
			delete _pAdoRS;
		}
		std::cout << sql << std::endl;
		_pAdoRS = new CADORecordset(_connectionHandlerPtr);
		try
		{
			_pAdoRS->Open(sql.c_str());
		}
		catch(CADOException& e)
		{
			TRACE(e.GetErrorMessage());
			delete _pAdoRS;
			_pAdoRS = NULL;
		}
	}

	void populate(ResultSet& rs)
	{
		try
		{
			CString strValue;
			while ( !_pAdoRS->IsEOF())
			{
				std::vector<std::string> myRow;
				for (int nRow = 0; nRow < _pAdoRS->GetFieldCount(); ++nRow)
				{
					_pAdoRS->GetFieldValue(nRow,strValue);
				 	myRow.push_back(strValue.GetBuffer(0));
					strValue.ReleaseBuffer();
				}
				rs.addRow(myRow);
				_pAdoRS->MoveNext();
			}

			std::map<std::string,size_t> _fieldIndex;
			CADOFieldInfo adoFieldInfo;
			for (int nCol = 0; nCol < _pAdoRS->GetFieldCount(); ++nCol)
			{
				_pAdoRS->GetFieldInfo(nCol,&adoFieldInfo);
				_fieldIndex[adoFieldInfo.m_strName] = nCol;
			}
			rs._fieldIndex = _fieldIndex;
			delete _pAdoRS;
			_pAdoRS = NULL;
		}
		catch(CADOException& e)
		{
			TRACE(e.GetErrorMessage());
			delete _pAdoRS;
			_pAdoRS = NULL;

		}
	}

protected:

	void close(void)
	{
		if (_connectionHandlerPtr != NULL)
		{		
			delete _connectionHandlerPtr;
		}
		if (_pAdoRS == NULL)
		{
			delete _pAdoRS;
		}
	}

private:

	CADODatabase* _connectionHandlerPtr;
	CADORecordset* _pAdoRS;
}; 


}